package com.myworld.config;

import java.lang.reflect.Method;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport{
	
	/**
	 * ridis缓存超时时间
	 */
	@Value("${spring.cached.redis.timeout}")
	private int cacheRedisTimeout=100000;
	
	/**
	 * 缓存管理器
	 * @param redisTemplate
	 * @return
	 */
	@Bean
	public CacheManager  cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate){
		RedisCacheManager cacheManager=new RedisCacheManager(redisTemplate);
		//设置缓存过期时间
		System.out.println("redisCache缓存 cacheRedisTimeout:"+cacheRedisTimeout);
		cacheManager.setDefaultExpiration(cacheRedisTimeout);
		return cacheManager;		
	}
	
	/**
	 * redisTemplate
	 */
    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
        redisTemplate.setConnectionFactory(factory);
        redisTemplate.afterPropertiesSet();
        setSerializer(redisTemplate);//设置序列化工具
        return redisTemplate;
    }
    
    /**
     * 修改redisTemplate序列化的方式
     * @param redisTemplate
     */
	private void setSerializer(RedisTemplate<String, String> redisTemplate) {
		 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
	        ObjectMapper om = new ObjectMapper();
	        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
	        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
	        jackson2JsonRedisSerializer.setObjectMapper(om);
	        redisTemplate.setKeySerializer(new StringRedisSerializer());
	        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
	}
	
	/**
	 * 重新该方法的作用：
	 * 自定义默认key 的值，该代码中重写的key为：  类名+方法名+参数值
	 */
	/*@Override
    public KeyGenerator keyGenerator() {
             System.out.println("RedisCacheConfig.keyGenerator()");
             return new KeyGenerator(){
                    @Override
                    public Object generate(Object o, Method method, Object... objects) {                      
                           StringBuilder sb =new StringBuilder();
                           sb.append(o.getClass().getName());
                           sb.append(method.getName());
                           for (Object obj : objects) {
                                 sb.append(obj.toString());
                           }
                           System.out.println("keyGenerator=" +sb.toString());
                           return sb.toString();
                    }

             };

      }*/
}
